package edu.neu.cloud_factory.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import edu.neu.cloud_factory.entity.po.Bid;
import edu.neu.cloud_factory.entity.po.Factory;
import edu.neu.cloud_factory.entity.po.Order;
import edu.neu.cloud_factory.entity.po.User;
import edu.neu.cloud_factory.entity.vo.BidVo;
import edu.neu.cloud_factory.service.BidService;
import edu.neu.cloud_factory.service.FactoryService;
import edu.neu.cloud_factory.service.OrderService;
import edu.neu.cloud_factory.service.UserService;
import edu.neu.cloud_factory.utils.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 竞标 前端控制器
 * </p>
 *
 * @author halozhy
 * @since 2021-07-15
 */
@RestController
@RequestMapping("/api/bid")
public class BidController {
    @Autowired
    BidService bidService;

    @Autowired
    FactoryService factoryService;

    @Autowired
    OrderService orderService;

    @Autowired
    UserService userService;

    @GetMapping("/list_by_oId")
    public List<BidVo> listByOrderId(long oId) {
        QueryWrapper<Bid> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("b_order_id", oId);
        List<Bid> bidList = bidService.list(queryWrapper);
        List<Factory> factoryList = factoryService.list();
        Map<Long, Factory> factoryMap = new HashMap<>();
        factoryList.forEach(factory -> {
            factoryMap.put(factory.getFId(), factory);
        });
        List<BidVo> bidVoList = new ArrayList<>();
        bidList.forEach(bid -> {
            BidVo bidVo = new BidVo();
            bidVo.setId(bid.getBId());
            bidVo.setOrder_id(bid.getBOrderId());
            bidVo.setPrice(bid.getBPrice());
            bidVo.setAccept_num(bid.getBAcceptNum());
            bidVo.setWin_num(bid.getBWinNum());
            bidVo.setBid_time(bid.getBBidTime());
            bidVo.setState(bid.getBState());
            bidVo.setWin_time(bid.getBWinTime());
            bidVo.setFac_id(bid.getBFactoryId());

            bidVo.setFac_name(factoryMap.get(bid.getBFactoryId()).getFName());
            bidVo.setFac_describe(factoryMap.get(bid.getBFactoryId()).getFDescribe());
            bidVoList.add(bidVo);
        });
        return bidVoList;
    }

    // 投标
    @PostMapping("/bid")
    public int bid(@RequestBody String CONTENT) {
        JSONObject j = JSONObject.parseObject(CONTENT);
        if (Utils.checkEmpty(j, Arrays.asList("user_id", "bid_price", "order_id"))) {
            float bidPrice = j.getFloat("bid_price");
            long orderId = j.getLong("order_id");
            // 订单是否存在
            Order order = orderService.getById(orderId);
            if (order == null) {
                return -1; // 订单不存在
            }
            // 用户是否存在
            User u = userService.getById(j.getLong("user_id"));
            if (u == null){
                return -4; // 用户不存在
            }
            // 订单此状态下是否还可竞标 订单状态 == 已发布？
            if (order.getOState().equals("已发布")){
                // 添加竞标信息
                Bid bid = new Bid();
                bid.setBFactoryId(u.getUFactoryId());
                bid.setBOrderId(orderId);
                bid.setBPrice(BigDecimal.valueOf(bidPrice));
                // 暂且为全部数量竞标
                bid.setBAcceptNum(order.getONum());
                bid.setBBidTime(LocalDateTime.now());
                bid.setBState("已投标");
                bidService.save(bid);
                // [弃用] 另外，bid关联的订单状态要改为 已投标
//                order.setOState("已投标");
//                orderService.updateById(order);
                return 0;
            }
            else {
                return -3; // 订单状态不合法，不能竞标
            }
        }
        return -2; // 未填写完整
    }

    @PostMapping("/can_bid")
    public JSONObject canBid(@RequestBody String CONTENT) {
        // 检查某用户对某订单，是否可以竞标，如果已经竞标过，那么就要返回竞标价格
        JSONObject j = JSONObject.parseObject(CONTENT);
        JSONObject result = new JSONObject();
        if (Utils.checkEmpty(j, Arrays.asList("user_id", "order_id"))) {
            long orderId = j.getLong("order_id");
            // 订单是否存在
            Order order = orderService.getById(orderId);
            if (order == null) {
                result.put("data", -1);
                return result;
//                return -1; // 订单不存在
            }
            // 用户是否存在
            User u = userService.getById(j.getLong("user_id"));
            if (u == null) {
                result.put("data", -4);
                return result;
//                return -4; // 用户不存在
            }
            // 此用户有没有竞标过
            QueryWrapper<Bid> queryWrapper = new QueryWrapper<>();
            Factory factory = factoryService.getById(u.getUFactoryId());
            if (factory == null) {
                result.put("data", -5);
                return result;
//                return -5; // 工厂不存在
            }
            queryWrapper.eq("b_factory_id", factory.getFId());
            queryWrapper.eq("b_order_id", order.getOId());
            List<Bid> bidList = bidService.list(queryWrapper);
            if (bidList.size() == 0) {
                result.put("data", 0);
            } else {
                result.put("data", 1);
                result.put("price", bidList.get(0).getBPrice()); // 目前认为一个用户只能对一个订单竞标一次
            }
            return result;
        }
        result.put("data", -2);
        return result;
//        return -2; // 未填写完整
    }

    // 中标，（选择一个投标以确定）
    @PostMapping("choose_bid")
    public int chooseBid(@RequestBody String CONTENT){
        JSONObject j = JSONObject.parseObject(CONTENT);
        JSONObject result = new JSONObject();
        if (Utils.checkEmpty(j, Arrays.asList("user_id", "order_id", "bid_id"))) {
            long orderId = j.getLong("order_id");
            // 订单是否存在
            Order order = orderService.getById(orderId);
            if (order == null) {
                return -1; // 订单不存在
            }
            // 用户是否存在
            User u = userService.getById(j.getLong("user_id"));
            if (u == null) {
                return -4; // 用户不存在
            }
            // 竞标信息是否存在
            Bid bid = bidService.getById(j.getLong("bid_id"));
            if (bid == null) {
                return -5; // 竞标信息不存在
            }
            // 此订单现在是否处于已发布状态
            if (!order.getOState().equals("已发布")){
                return -6; // 订单状态不合法
            }
            // 确定了某一家工厂(某一个bid)，修改bid状态为 已中标，设置win_num = accept_num, win_time = now()
            bid.setBState("已中标");
            bid.setBWinNum(bid.getBAcceptNum());
            bid.setBWinTime(LocalDateTime.now());
            bidService.updateById(bid);
            // 确定某一家工厂(某一个bid)之后，此订单的其它工厂的投标状态改为未中标
            QueryWrapper<Bid> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("b_order_id", order.getOId());
            List<Bid> bidList = bidService.list(queryWrapper);
            for (int i = 0; i < bidList.size(); i++) {
                Bid b = bidList.get(i);
                if (b.getBId().equals(j.getLong("bid_id"))){
                    // 跳过中了标的
                    continue;
                }
                else {
                    b.setBState("未中标");
                    bidService.updateById(b);
                }
            }
            // 设置订单的状态为 已中标
            order.setOState("已中标");
            orderService.updateById(order);
            return 0;
        }
        return -2;
    }
}

